package com.itdct.onflow.system.common.websocket

import com.alibaba.fastjson2.parseObject
import com.itdct.onflow.core.extend.logInfo
import com.itdct.onflow.core.extend.logWarn
import com.itdct.onflow.core.util.RedisUtil
import com.itdct.onflow.system.account.constant.SysAccountRedisKey
import com.itdct.onflow.system.common.base.LoginDTO

import org.springframework.context.annotation.Configuration
import org.springframework.http.server.ServerHttpRequest
import org.springframework.http.server.ServerHttpResponse
import org.springframework.web.socket.WebSocketHandler
import org.springframework.web.socket.server.HandshakeInterceptor

/**
 * @author Zhouwx
 * @date 2025/2/24 17:15:03
 * @version 1.0
 * @description
 */
@Configuration
class AuthHandshakeInterceptor(
    val redisUtil: RedisUtil
) : HandshakeInterceptor {

    override fun beforeHandshake(
        request: ServerHttpRequest,
        response: ServerHttpResponse,
        wsHandler: WebSocketHandler,
        attributes: MutableMap<String, Any>
    ): Boolean {
        // 从请求参数中获取token（实际应从header获取更安全）
        val urlMap = HashMap<String, String>()
        request.uri.query?.also {
            val split = it.split("&")
            for (pairString in split) {
                val splitPair = pairString.split("=")
                if (splitPair.size == 2) {
                    urlMap[splitPair[0]] = splitPair[1]
                }
            }
        }
        val token = urlMap["token"]
        val type = urlMap["type"]

        return try {
            // 验证token逻辑（示例使用简单验证）
            val accountLoginDto = verifyToken(token, type)

            // 将用户ID存入会话属性
            attributes["accountToken"] = "${accountLoginDto.accountId}_${token}"
            attributes["accountId"] = accountLoginDto.accountId
            logInfo("Authenticated user: ${accountLoginDto.accountId}")
            true
        } catch (e: Exception) {
            logWarn("Authentication failed: ${e.message}")
            false
        }
    }

    override fun afterHandshake(
        request: ServerHttpRequest,
        response: ServerHttpResponse,
        wsHandler: WebSocketHandler,
        exception: Exception?
    ) {
        logInfo("afterHandshake")
        // 握手后处理（可选）
    }

    private fun verifyToken(token: String?, type: String?): LoginDTO {
        // 示例简单验证，实际应使用JWT等验证机制
        if (token.isNullOrEmpty()) throw IllegalArgumentException("Missing token")
        if (type.isNullOrEmpty()) throw IllegalArgumentException("Missing type")
        if (token == "invalid_token") throw IllegalArgumentException("Invalid token")
        val tokenKey = SysAccountRedisKey.LOGIN_TOKEN(token)
        val tokenInfo = redisUtil.get(tokenKey) as String?
        if (tokenInfo == null) throw IllegalArgumentException("Token not found")

        val loginDto = tokenInfo.parseObject<LoginDTO>()
        if (loginDto.platformType.lowercase() != type) {
            throw IllegalArgumentException("客户端类型无法匹配")
        }

        // 返回用户ID（示例逻辑）
        return loginDto
    }
}